#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
TaoBao自动化爬虫
"""

import logging
import time
import json
import os
import sys
import getpass
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.common.exceptions import TimeoutException, NoSuchElementException, WebDriverException
from typing import List, Dict, Any

# 添加项目根目录到路径（用于导入webdriver_manager_util）
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if project_root not in sys.path:
    sys.path.insert(0, project_root)

# 导入WebDriver管理器
try:
    from webdriver_manager_util import WebDriverManager
except ImportError:
    print("⚠️ 无法导入webdriver_manager_util，将使用传统方式")
    WebDriverManager = None

from TaoBao.config import TaoBaoConfig


class TaoBaoScraper:
    """TaoBao爬虫类"""
    
    def __init__(self, headless=False, debug=False):
        """初始化爬虫"""
        self.headless = headless
        self.debug = debug
        self.driver = None
        self.wait = None
        self.config = TaoBaoConfig
        
        # GUI回调函数
        self.login_confirmation_callback = None
        self.verification_callback = None
        self.credential_input_callback = None
        
        # 配置日志
        self._setup_logging()
        
        self.logger.info(f"TaoBao爬虫初始化完成 - headless: {headless}, debug: {debug}")
    
    def _setup_logging(self):
        """配置日志"""
        self.logger = logging.getLogger('TaoBaoScraper')
        if not self.logger.handlers:
            handler = logging.StreamHandler()
            formatter = logging.Formatter(self.config.LOG_FORMAT)
            handler.setFormatter(formatter)
            self.logger.addHandler(handler)
            self.logger.setLevel(getattr(logging, self.config.LOG_LEVEL))
    
    def __enter__(self):
        """上下文管理器入口"""
        self.init_driver()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """上下文管理器出口"""
        self.close()
    
    def init_driver(self):
        """初始化浏览器驱动"""
        try:
            chrome_options = Options()
            
            # 添加基本选项
            for option in self.config.CHROME_OPTIONS:
                chrome_options.add_argument(option)
            
            if self.headless:
                chrome_options.add_argument("--headless")
            
            # 禁用自动化检测
            chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
            chrome_options.add_experimental_option('useAutomationExtension', False)
            
            # 设置用户代理
            chrome_options.add_argument(f"--user-agent={self.config.get_random_user_agent()}")
            
            # 尝试使用WebDriverManager自动管理ChromeDriver
            if WebDriverManager:
                try:
                    self.logger.info("🔍 使用WebDriverManager自动配置ChromeDriver...")
                    manager = WebDriverManager(logger=self.logger)
                    self.driver = manager.get_chrome_driver(options=chrome_options, headless=self.headless)
                    self.logger.info("✅ ChromeDriver自动配置成功")
                except Exception as e:
                    self.logger.warning(f"⚠️ WebDriverManager初始化失败: {e}")
                    self.logger.info("🔄 回退到传统方式...")
                    self._init_driver_legacy(chrome_options)
            else:
                # 如果没有WebDriverManager，使用传统方式
                self._init_driver_legacy(chrome_options)
            
            # 执行隐藏自动化特征的脚本
            self.driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
            
            # 设置等待
            self.wait = WebDriverWait(self.driver, self.config.DEFAULT_TIMEOUT)
            
            self.logger.info("浏览器驱动初始化成功")
            
        except Exception as e:
            self.logger.error(f"浏览器驱动初始化失败: {e}")
            raise
    
    def _init_driver_legacy(self, chrome_options):
        """传统方式初始化driver（备用方案）"""
        try:
            # 尝试使用本地chromedriver
            if os.path.exists(self.config.CHROME_DRIVER_PATH):
                self.logger.info(f"📂 使用本地ChromeDriver: {self.config.CHROME_DRIVER_PATH}")
                service = Service(executable_path=self.config.CHROME_DRIVER_PATH)
                self.driver = webdriver.Chrome(service=service, options=chrome_options)
            else:
                self.logger.info("🔄 使用系统PATH中的ChromeDriver")
                self.driver = webdriver.Chrome(options=chrome_options)
                
        except Exception as e:
            self.logger.error(f"❌ 传统方式初始化ChromeDriver失败: {e}")
            raise
    
    def close(self):
        """关闭浏览器"""
        try:
            if self.driver:
                self.driver.quit()
                self.logger.info("浏览器已关闭")
        except Exception as e:
            self.logger.error(f"关闭浏览器失败: {e}")
    
    # ==================== 导航和页面操作 ====================
    
    def navigate_to_login_page(self) -> bool:
        """直接导航到登录页面"""
        try:
            login_url = "https://login.taobao.com/"
            self.logger.info(f"🚀 直接导航到登录页面: {login_url}")
            self.driver.get(login_url)
            
            # 等待页面加载
            time.sleep(5)
            
            # 验证登录页面加载成功
            current_url = self.driver.current_url
            page_title = self.driver.title
            
            self.logger.info(f"当前URL: {current_url}")
            self.logger.info(f"页面标题: {page_title}")
            
            # 检查是否成功到达登录页面
            if 'login.taobao.com' in current_url or '登录' in page_title:
                self.logger.info("✅ 成功导航到淘宝登录页面")
                
                # 等待登录表单加载
                try:
                    self.wait_for_element(By.CSS_SELECTOR, self.config.SELECTORS['login']['username_input'], timeout=10)
                    self.logger.info("✅ 登录表单已加载")
                    return True
                except:
                    self.logger.warning("⚠️ 登录表单加载超时，但页面已到达")
                    return True
            else:
                self.logger.error(f"❌ 未能到达登录页面，当前URL: {current_url}")
                return False
                
        except Exception as e:
            self.logger.error(f"导航到登录页面失败: {e}")
            return False
    
    def navigate_to_shop(self, shop_url):
        """导航到店铺页面"""
        try:
            self.logger.info(f"导航到店铺: {shop_url}")
            
            # 访问店铺页面
            self.driver.get(shop_url)
            
            # 等待页面加载
            time.sleep(self.config.WAIT_TIMES['medium'])
            
            # 检查页面是否加载成功
            current_url = self.driver.current_url
            page_title = self.driver.title
            
            self.logger.info(f"当前URL: {current_url}")
            self.logger.info(f"页面标题: {page_title}")
            
            # 检查是否被重定向到手机版
            if "m.taobao.com" in current_url and "m.taobao.com" not in shop_url:
                self.logger.info("🔍 检测到被重定向到手机版")
                
                # 尝试跳转到PC版
                pc_url = current_url.replace("m.taobao.com", "shop.taobao.com").replace(".m.taobao.com", ".taobao.com")
                if pc_url != current_url:
                    self.logger.info(f"🔄 尝试跳转到PC版: {pc_url}")
                    try:
                        self.driver.get(pc_url)
                        time.sleep(self.config.WAIT_TIMES['medium'])
                        current_url = self.driver.current_url
                        self.logger.info(f"🔄 跳转后URL: {current_url}")
                    except Exception as redirect_e:
                        self.logger.warning(f"⚠️ 跳转PC版失败: {redirect_e}")
            
            # 简单验证是否到达了淘宝页面
            if "taobao.com" in current_url:
                if "m.taobao.com" in current_url:
                    self.logger.info("✅ 成功导航到淘宝页面 (手机版)")
                else:
                    self.logger.info("✅ 成功导航到淘宝页面 (PC版)")
                return True
            else:
                self.logger.warning(f"⚠️ 可能被重定向到其他页面: {current_url}")
                return False
                
        except Exception as e:
            self.logger.error(f"导航到店铺失败: {e}")
            return False
    
    def check_login_required(self):
        """检查是否需要登录"""
        try:
            self.logger.info("检查登录状态...")
            
            # 方法1: 检查登录提示文本
            login_text_elements = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_text_indicator'])
            if login_text_elements:
                login_text = login_text_elements[0].text
                self.logger.info(f"发现登录提示: {login_text}")
                if "登录后" in login_text:
                    self.logger.info("🔐 需要登录才能查看完整内容")
                    return True
            
            # 方法2: 检查是否有"亲，请登录"链接
            nav_login_elements = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_button_nav'])
            if nav_login_elements:
                nav_login_text = nav_login_elements[0].text
                self.logger.info(f"导航栏登录链接: {nav_login_text}")
                if "请登录" in nav_login_text:
                    self.logger.info("🔐 检测到未登录状态")
                    return True
            
            # 方法3: 检查是否有登录容器
            login_containers = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_container'])
            if login_containers:
                self.logger.info("🔐 检测到登录容器，需要登录")
                return True
            
            # 方法4: 检查是否有用户信息（已登录状态）
            user_info_elements = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_success_indicator'])
            if user_info_elements:
                self.logger.info("✅ 检测到用户信息，已登录状态")
                return False
            
            # 默认认为需要登录
            self.logger.info("🔐 无法确定登录状态，默认需要登录")
            return True
            
        except Exception as e:
            self.logger.error(f"检查登录状态失败: {e}")
            return True
    
    def handle_login_prompt(self):
        """处理登录提示"""
        try:
            self.logger.info("处理登录提示...")
            
            # 检查当前URL，判断是否为手机版
            current_url = self.driver.current_url
            is_mobile = "m.taobao.com" in current_url
            
            if is_mobile:
                self.logger.info("🔍 检测到手机版页面，使用手机版登录策略")
                return self._handle_mobile_login()
            else:
                self.logger.info("🔍 检测到PC版页面，使用PC版登录策略")
                return self._handle_pc_login()
                
        except Exception as e:
            self.logger.error(f"处理登录提示失败: {e}")
            return False
    
    def _handle_pc_login(self):
        """处理PC版登录"""
        try:
            # 尝试点击页面中的"立即登录"按钮
            page_login_buttons = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_button_page'])
            if page_login_buttons:
                self.logger.info("发现页面登录按钮，尝试点击...")
                login_button = page_login_buttons[0]
                self.scroll_to_element(login_button)
                
                if self.safe_click(login_button):
                    self.logger.info("✅ 成功点击页面登录按钮")
                    time.sleep(self.config.WAIT_TIMES['medium'])
                    
                    # 检查是否跳转到登录页面或打开了新窗口
                    return self._verify_login_page_opened()
                else:
                    self.logger.warning("❌ 点击页面登录按钮失败")
            
            # 如果页面登录按钮不可用，尝试点击导航栏的登录链接
            nav_login_buttons = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_button_nav'])
            if nav_login_buttons:
                self.logger.info("发现导航栏登录链接，尝试点击...")
                nav_login_button = nav_login_buttons[0]
                
                if self.safe_click(nav_login_button):
                    self.logger.info("✅ 成功点击导航栏登录链接")
                    time.sleep(self.config.WAIT_TIMES['medium'])
                    
                    # 检查是否跳转到登录页面或打开了新窗口
                    return self._verify_login_page_opened()
                else:
                    self.logger.warning("❌ 点击导航栏登录链接失败")
            
            return False
            
        except Exception as e:
            self.logger.error(f"PC版登录处理失败: {e}")
            return False
    
    def _handle_mobile_login(self):
        """处理手机版登录"""
        try:
            self.logger.info("搜索手机版登录入口...")
            
            # 先尝试通用的登录按钮搜索
            for selector in self.config.SELECTORS['login']['mobile_login_buttons']:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        self.logger.info(f"通过选择器 '{selector}' 找到 {len(elements)} 个元素")
                        for i, element in enumerate(elements):
                            try:
                                element_text = element.text.strip()
                                self.logger.info(f"  元素 {i+1}: 文本='{element_text}', 标签={element.tag_name}")
                                
                                # 检查是否包含登录相关关键词
                                if any(keyword in element_text for keyword in ["登录", "账号", "密码"]):
                                    self.logger.info(f"🎯 找到疑似登录按钮: {element_text}")
                                    self.scroll_to_element(element)
                                    
                                    if self.safe_click(element):
                                        self.logger.info("✅ 成功点击手机版登录按钮")
                                        time.sleep(self.config.WAIT_TIMES['medium'])
                                        return True
                            except Exception as elem_e:
                                self.logger.debug(f"处理元素时出错: {elem_e}")
                                continue
                except Exception as sel_e:
                    self.logger.debug(f"选择器 '{selector}' 搜索失败: {sel_e}")
                    continue
            
            # 如果通用搜索失败，尝试更广泛的文本搜索
            self.logger.info("尝试通过文本内容搜索登录入口...")
            try:
                # 搜索所有包含"登录"文本的元素
                login_text_elements = self.driver.find_elements(By.XPATH, "//*[contains(text(), '登录')]")
                self.logger.info(f"找到包含'登录'文本的元素: {len(login_text_elements)} 个")
                
                for element in login_text_elements[:5]:  # 限制搜索前5个
                    try:
                        element_text = element.text.strip()
                        if element_text and len(element_text) <= 20:  # 避免太长的文本
                            self.logger.info(f"🔍 检查登录元素: '{element_text}'")
                            
                            # 检查是否是可点击的登录入口
                            if any(keyword in element_text for keyword in ["账号密码登录", "密码登录", "立即登录"]):
                                self.logger.info(f"🎯 找到目标登录入口: {element_text}")
                                self.scroll_to_element(element)
                                
                                if self.safe_click(element):
                                    self.logger.info("✅ 成功点击登录入口")
                                    time.sleep(self.config.WAIT_TIMES['medium'])
                                    return True
                    except Exception as text_e:
                        self.logger.debug(f"处理登录文本元素时出错: {text_e}")
                        continue
                        
            except Exception as xpath_e:
                self.logger.error(f"XPath搜索失败: {xpath_e}")
            
            self.logger.warning("⚠️ 未找到可用的手机版登录入口")
            return False
            
        except Exception as e:
            self.logger.error(f"手机版登录处理失败: {e}")
            return False
            
        except Exception as e:
            self.logger.error(f"处理登录提示失败: {e}")
            return False
    
    def login_taobao(self, mode: str = "interactive"):
        """
        淘宝登录 - 支持GUI回调
        
        Args:
            mode: 登录模式 ("interactive" 或 "manual")
            
        Returns:
            bool: 登录是否成功
        """
        try:
            self.logger.info(f"开始淘宝登录流程 - 模式: {mode}")
            
            # 导航到登录页面
            login_url = "https://login.taobao.com/"
            self.driver.get(login_url)
            time.sleep(3)
            
            if mode == "interactive":
                return self._interactive_taobao_login()
            elif mode == "manual":
                return self._manual_taobao_login()
            else:
                self.logger.error(f"不支持的登录模式: {mode}")
                return False
                
        except Exception as e:
            self.logger.error(f"淘宝登录失败: {e}")
            return False
    
    def _interactive_taobao_login(self):
        """交互式淘宝登录"""
        try:
            self.logger.info("开始交互式淘宝登录")
            
            # 等待页面加载
            time.sleep(self.config.WAIT_TIMES['medium'])
            
            # 获取用户凭证
            if hasattr(self, 'credential_input_callback') and self.credential_input_callback:
                # 使用GUI回调获取凭证
                credentials = self.credential_input_callback("淘宝")
                if not credentials:
                    self.logger.error("用户取消登录")
                    return False
                username, password = credentials
            else:
                # 命令行交互式输入
                print("\n" + "="*60)
                print("🔐 淘宝登录页面已打开")
                print("="*60)
                print("📝 请输入你的淘宝登录信息:")
                print("-"*60)
                
                username = input("👤 请输入淘宝账号/手机号: ").strip()
                password = input("🔑 请输入登录密码: ").strip()
            
            if not username or not password:
                self.logger.error("❌ 账号或密码不能为空")
                return False
            
            # 尝试自动填充登录表单
            try:
                # 查找用户名输入框
                username_input = self.driver.find_element(By.CSS_SELECTOR, self.config.SELECTORS['login']['username_input'])
                username_input.clear()
                username_input.send_keys(username)
                time.sleep(1)
                
                # 查找密码输入框
                password_input = self.driver.find_element(By.CSS_SELECTOR, self.config.SELECTORS['login']['password_input'])
                password_input.clear()
                password_input.send_keys(password)
                time.sleep(1)
                
                # 查找并点击登录按钮
                submit_button = self.driver.find_element(By.CSS_SELECTOR, self.config.SELECTORS['login']['submit_button'])
                submit_button.click()
                
                self.logger.info("已提交登录表单")
                
            except Exception as form_e:
                self.logger.warning(f"自动填充表单失败: {form_e}")
                print("⚠️ 自动填充失败，请手动输入登录信息")
            
            # 等待登录完成
            return self._wait_for_taobao_login_success()
            
        except Exception as e:
            self.logger.error(f"交互式淘宝登录失败: {e}")
            return False
    
    def _manual_taobao_login(self):
        """手动淘宝登录"""
        try:
            self.logger.info("开始手动淘宝登录")
            
            print("\n" + "="*60)
            print("👤 淘宝手动登录模式")
            print("="*60)
            print("请在浏览器中手动完成登录操作")
            print("-"*60)
            print("📋 操作步骤:")
            print("   1. 输入淘宝账号/手机号")
            print("   2. 输入密码")
            print("   3. 处理验证码（如果出现）")
            print("   4. 点击登录按钮")
            print("   5. 等待登录成功")
            print("-"*60)
            
            # 显示当前页面信息
            print(f"📍 当前页面: {self.driver.current_url}")
            print(f"📄 页面标题: {self.driver.title}")
            
            # 等待用户手动登录
            if hasattr(self, 'login_confirmation_callback') and self.login_confirmation_callback:
                # 使用GUI回调确认
                confirmed = self.login_confirmation_callback("淘宝")
            else:
                # 命令行模式
                input("\n✋ 请在浏览器中完成登录操作，然后按 Enter 键继续...")
                confirmed = True
            
            if confirmed:
                # 检查登录状态
                if self._check_taobao_login_success():
                    self.logger.info("✅ 淘宝手动登录完成")
                    return True
                else:
                    self.logger.error("❌ 淘宝登录验证失败")
                    return False
            else:
                self.logger.info("❌ 用户取消淘宝登录")
                return False
                
        except Exception as e:
            self.logger.error(f"手动淘宝登录失败: {e}")
            return False
    
    def _wait_for_taobao_login_success(self):
        """等待淘宝登录成功"""
        try:
            # 等待登录完成
            time.sleep(5)
            
            # 检查登录是否成功
            if self._check_taobao_login_success():
                self.logger.info("✅ 淘宝登录成功")
                return True
            else:
                # 检查是否有验证码
                if self._check_taobao_verification_needed():
                    if hasattr(self, 'verification_callback') and self.verification_callback:
                        # 使用GUI回调处理验证码
                        action = self.verification_callback("淘宝", "登录验证")
                        if action == 'continue':
                            # 再次等待登录完成
                            time.sleep(5)
                            return self._check_taobao_login_success()
                        elif action == 'skip':
                            return False
                        elif action == 'quit':
                            return False
                    else:
                        # 命令行模式处理验证码
                        print("⚠️ 检测到验证码，请手动处理...")
                        input("处理完成后按 Enter 继续...")
                        return self._check_taobao_login_success()
                
                self.logger.error("❌ 淘宝登录失败")
                return False
                
        except Exception as e:
            self.logger.error(f"等待淘宝登录完成时出错: {e}")
            return False
    
    def _check_taobao_login_success(self):
        """检查淘宝登录是否成功"""
        try:
            current_url = self.driver.current_url
            
            # 检查URL是否不再包含login
            if "login" not in current_url.lower() and "taobao.com" in current_url:
                return True
            
            # 检查是否有用户信息元素
            user_info_selectors = [
                ".site-nav-user", ".site-nav-login-info", ".j_username",
                "[class*='user']", ".user-info", ".user-name"
            ]
            
            for selector in user_info_selectors:
                try:
                    user_info = self.driver.find_element(By.CSS_SELECTOR, selector)
                    if user_info and user_info.is_displayed():
                        return True
                except:
                    continue
            
            return False
            
        except Exception as e:
            self.logger.error(f"检查淘宝登录状态失败: {e}")
            return False
    
    def _check_taobao_verification_needed(self):
        """检查是否需要验证码处理"""
        try:
            # 检查常见的验证码元素
            verification_elements = [
                "#baxia-password", ".baxia-container", ".tb-login",
                ".captcha", ".verification", ".verify",
                "[class*='captcha']", "[class*='verify']",
                "iframe[src*='captcha']", "iframe[src*='verify']"
            ]
            
            for selector in verification_elements:
                elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                if elements:
                    return True
            
            return False
            
        except Exception:
            return False
    
    def login_taobao_old(self):
        """淘宝登录 (交互式)"""
        try:
            self.logger.info("开始淘宝登录流程...")
            
            # 获取当前URL，判断是否在登录页面
            current_url = self.driver.current_url
            self.logger.info(f"当前URL: {current_url}")
            
            # 更智能的登录页面检测 - 检查所有窗口
            login_page_found = False
            window_handles = self.driver.window_handles
            
            # 如果有多个窗口，检查所有窗口
            if len(window_handles) > 1:
                for i, handle in enumerate(window_handles):
                    try:
                        self.driver.switch_to.window(handle)
                        time.sleep(1)
                        check_url = self.driver.current_url
                        login_indicators = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_page_indicator'])
                        
                        self.logger.info(f"检查窗口 {i+1}: URL={check_url}, 登录元素={len(login_indicators)}个")
                        
                        if login_indicators or "login" in check_url:
                            self.logger.info(f"✅ 在窗口 {i+1} 找到登录页面")
                            login_page_found = True
                            break
                    except Exception as window_e:
                        self.logger.debug(f"检查窗口 {i+1} 失败: {window_e}")
                        continue
            else:
                # 单窗口检测
                login_indicators = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_page_indicator'])
                if login_indicators or "login" in current_url:
                    login_page_found = True
            
            if not login_page_found:
                self.logger.info("当前不在登录页面，可能需要先触发登录")
                return False
            
            # 等待登录页面加载
            time.sleep(self.config.WAIT_TIMES['medium'])
            
            # 检查登录表单是否存在
            login_form = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_form'])
            username_input = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['username_input'])
            password_input = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['password_input'])
            
            if not (login_form and username_input and password_input):
                self.logger.warning("⚠️ 登录表单元素未找到，可能页面结构发生变化")
                print("⚠️ 登录表单元素未找到，将采用通用交互式登录")
            else:
                self.logger.info(f"✅ 检测到登录表单元素: 用户名输入框={len(username_input)}, 密码输入框={len(password_input)}")
            
            # 交互式登录提示
            print("\n" + "="*60)
            print("🔐 淘宝登录页面已打开")
            print("="*60)
            print("📝 请输入你的淘宝登录信息:")
            print("-"*60)
            
            # 获取用户输入的账号密码
            print("💬 请按提示输入登录信息...")
            sys.stdout.flush()  # 强制刷新输出缓冲区
            
            username = input("👤 请输入淘宝账号/手机号: ").strip()
            print(f"✅ 已接收用户名: {username[:3]}***")
            sys.stdout.flush()
            
            # 测试阶段使用普通input，避免getpass在某些环境下的问题
            password = input("🔑 请输入登录密码: ").strip()
            print("✅ 已接收密码")
            sys.stdout.flush()
            
            if not username or not password:
                self.logger.error("❌ 账号或密码不能为空")
                print("❌ 账号或密码不能为空")
                return False
            
            # 自动填写登录表单
            print("\n🤖 正在自动填写登录信息...")
            sys.stdout.flush()
            
            fill_result = self._fill_login_form(username, password)
            print(f"📊 填写结果: {'成功' if fill_result else '失败'}")
            sys.stdout.flush()
            
            if fill_result:
                print("✅ 登录信息填写完成")
                print("📝 请在浏览器中完成以下操作:")
                print("1. 完成验证码验证 (如果有)")
                print("2. 系统已自动勾选用户协议并点击登录")
                print("3. 系统会自动处理可能出现的协议确认弹框")
                print("4. 等待验证通过后，回到此窗口按 Enter 键继续")
                print("-"*60)
                
                # 等待用户完成验证码验证
                input("✋ 验证完成后，请按 Enter 键继续...")
            else:
                print("❌ 自动填写失败，请手动在浏览器中完成登录")
                print("📝 请在浏览器中手动完成以下操作:")
                print("1. 输入账号和密码")
                print("2. 勾选'已阅读并同意以下协议'复选框")
                print("3. 完成验证码验证 (如果有)")
                print("4. 点击登录按钮")
                print("5. 等待登录成功后，回到此窗口按 Enter 键继续")
                print("-"*60)
                
                # 等待用户手动完成登录
                input("✋ 手动登录完成后，请按 Enter 键继续...")
            
            # 检查登录是否成功
            max_checks = 8
            for i in range(max_checks):
                current_url = self.driver.current_url
                page_title = self.driver.title
                
                self.logger.info(f"检查登录状态 ({i+1}/{max_checks}): {current_url}")
                
                # 检查是否还在登录页面
                login_indicators = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_page_indicator'])
                
                # 如果不在登录页面了，说明可能已经登录成功
                if not login_indicators and "login" not in current_url:
                    self.logger.info("✅ 已离开登录页面")
                    
                    # 进一步检查是否有用户信息
                    user_elements = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_success_indicator'])
                    if user_elements:
                        self.logger.info("✅ 检测到用户信息，登录成功！")
                        print("🎉 登录成功！")
                        return True
                    
                    # 检查是否回到了淘宝页面
                    if "taobao.com" in current_url:
                        self.logger.info("✅ 已返回淘宝页面，假设登录成功")
                        print("🎉 已返回淘宝页面！")
                        return True
                
                time.sleep(2)
            
            # 如果多次检查后仍无法确认，询问用户
            print("\n⚠️ 无法自动确认登录状态")
            user_confirm = input("请确认是否已成功登录? (y/n): ").strip().lower()
            
            if user_confirm in ['y', 'yes', '是']:
                self.logger.info("✅ 用户确认登录成功")
                return True
            else:
                self.logger.warning("❌ 用户确认登录失败")
                return False
                
        except Exception as e:
            self.logger.error(f"淘宝登录失败: {e}")
            return False
    
    # ==================== 商品列表操作 ====================
    
    def get_product_list(self, max_pages=None):
        """获取商品列表"""
        try:
            self.logger.info("🔍 开始获取商品列表...")
            print("🔍 正在获取商品列表...")
            sys.stdout.flush()
            
            # 等待页面加载
            time.sleep(3)
            
            # 滚动页面以加载所有商品
            self._scroll_to_load_products()
            
            # 查找商品卡片
            product_cards = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['product_list']['product_cards'])
            
            if not product_cards:
                self.logger.warning("⚠️ 未找到商品卡片")
                print("⚠️ 未找到商品，可能页面未完全加载")
                sys.stdout.flush()
                return []
            
            self.logger.info(f"✅ 找到 {len(product_cards)} 个商品")
            print(f"✅ 发现 {len(product_cards)} 个商品")
            sys.stdout.flush()
            
            products = []
            for i, card in enumerate(product_cards, 1):
                try:
                    self.logger.info(f"📦 处理第 {i} 个商品...")
                    print(f"📦 正在处理第 {i}/{len(product_cards)} 个商品...")
                    sys.stdout.flush()
                    
                    # 提取商品基本信息
                    product_info = self._extract_product_from_card(card, i)
                    if product_info:
                        products.append(product_info)
                        self.logger.info(f"✅ 第 {i} 个商品信息提取成功")
                        print(f"✅ 第 {i} 个商品信息提取完成")
                    else:
                        self.logger.warning(f"⚠️ 第 {i} 个商品信息提取失败")
                        print(f"⚠️ 第 {i} 个商品信息提取失败")
                    sys.stdout.flush()
                    
                except Exception as e:
                    self.logger.error(f"处理第 {i} 个商品时出错: {e}")
                    print(f"❌ 第 {i} 个商品处理出错: {e}")
                    sys.stdout.flush()
                    continue
            
            self.logger.info(f"📋 商品列表获取完成，共 {len(products)} 个有效商品")
            print(f"📋 商品列表获取完成，共 {len(products)} 个有效商品")
            sys.stdout.flush()
            
            return products
            
        except Exception as e:
            self.logger.error(f"获取商品列表失败: {e}")
            print(f"❌ 获取商品列表失败: {e}")
            sys.stdout.flush()
            return []
    
    def _extract_product_from_card(self, card, index):
        """从商品卡片提取基本信息"""
        try:
            product_info = {
                'index': index,
                'card_element': card  # 保存元素引用，用于后续点击
            }
            
            # 提取商品图片
            img_element = card.find_element(By.CSS_SELECTOR, 'img')
            if img_element:
                product_info['image_url'] = img_element.get_attribute('src') or img_element.get_attribute('data-src')
                self.logger.debug(f"商品 {index} 图片: {product_info['image_url']}")
            
            # 提取商品标题
            title_element = card.find_element(By.CSS_SELECTOR, self.config.SELECTORS['product_list']['product_title'])
            if title_element:
                product_info['title'] = title_element.text.strip()
                self.logger.debug(f"商品 {index} 标题: {product_info['title']}")
            
            # 提取商品价格 (淘宝价格通常是加密的，只能提取到加密字符串)
            try:
                price_element = card.find_element(By.CSS_SELECTOR, self.config.SELECTORS['product_list']['product_price'])
                if price_element:
                    price_text = price_element.text.strip()
                    product_info['price_display'] = price_text
                    self.logger.debug(f"商品 {index} 价格显示: {price_text}")
            except:
                product_info['price_display'] = "价格需登录查看"
            
            # 提取付款人数
            try:
                count_element = card.find_element(By.CSS_SELECTOR, self.config.SELECTORS['product_list']['product_count'])
                if count_element:
                    product_info['payment_count'] = count_element.text.strip()
                    self.logger.debug(f"商品 {index} 付款人数: {product_info['payment_count']}")
            except:
                product_info['payment_count'] = "0人付款"
            
            # 提取商品标签
            try:
                tags_elements = card.find_elements(By.CSS_SELECTOR, '.tags--ejYQ37YS span')
                if tags_elements:
                    product_info['tags'] = [tag.text.strip() for tag in tags_elements if tag.text.strip()]
                    self.logger.debug(f"商品 {index} 标签: {product_info['tags']}")
                else:
                    product_info['tags'] = []
            except:
                product_info['tags'] = []
            
            # 检查必要信息
            if not product_info.get('title'):
                self.logger.warning(f"商品 {index} 缺少标题信息")
                return None
            
            return product_info
            
        except Exception as e:
            self.logger.error(f"提取商品 {index} 信息失败: {e}")
            return None
    
    def extract_product_info_from_list(self, product_elements):
        """从列表页提取商品基本信息 (保持兼容性)"""
        try:
            products = []
            for i, element in enumerate(product_elements, 1):
                product_info = self._extract_product_from_card(element, i)
                if product_info:
                    products.append(product_info)
            return products
        except Exception as e:
            self.logger.error(f"提取商品信息失败: {e}")
            return []
    
    def _scroll_to_load_products(self):
        """滚动页面加载所有商品"""
        try:
            self.logger.info("📜 开始滚动页面加载商品...")
            print("📜 正在滚动页面加载更多商品...")
            sys.stdout.flush()
            
            last_height = self.driver.execute_script("return document.body.scrollHeight")
            scroll_attempts = 0
            max_scrolls = 5  # 最多滚动5次
            
            while scroll_attempts < max_scrolls:
                # 滚动到页面底部
                self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                time.sleep(2)  # 等待内容加载
                
                # 检查是否有"没有更多商品"的提示
                no_more_elements = self.driver.find_elements(By.CSS_SELECTOR, '.loadStatus--ctfp48MP')
                if no_more_elements:
                    for element in no_more_elements:
                        if "没有更多" in element.text:
                            self.logger.info("✅ 检测到'没有更多商品'，停止滚动")
                            print("✅ 已加载所有商品")
                            sys.stdout.flush()
                            return
                
                # 检查页面高度是否有变化
                new_height = self.driver.execute_script("return document.body.scrollHeight")
                if new_height == last_height:
                    # 没有新内容加载，尝试再滚动一次
                    scroll_attempts += 1
                    self.logger.info(f"⏳ 滚动第 {scroll_attempts} 次，等待内容加载...")
                    time.sleep(1)
                else:
                    # 有新内容，重置计数器
                    scroll_attempts = 0
                    last_height = new_height
                    self.logger.info("📄 检测到新内容，继续滚动...")
            
            self.logger.info("📜 滚动完成")
            print("📜 页面滚动完成")
            sys.stdout.flush()
            
        except Exception as e:
            self.logger.error(f"滚动页面失败: {e}")
            print(f"⚠️ 滚动页面出错: {e}")
            sys.stdout.flush()
    
    def scroll_to_load_more(self):
        """滚动加载更多商品 (保持兼容性)"""
        return self._scroll_to_load_products()
    
    # ==================== 商品详情操作 ====================
    
    def get_product_details(self, product_list):
        """获取商品详情"""
        try:
            self.logger.info(f"🔍 开始获取 {len(product_list)} 个商品的详细信息...")
            print(f"🔍 正在获取 {len(product_list)} 个商品的详细信息...")
            sys.stdout.flush()
            
            detailed_products = []
            main_window = self.driver.current_window_handle
            
            for i, product in enumerate(product_list, 1):
                try:
                    self.logger.info(f"📋 处理第 {i}/{len(product_list)} 个商品详情...")
                    print(f"📋 正在获取第 {i}/{len(product_list)} 个商品详情...")
                    sys.stdout.flush()
                    
                    # 点击商品进入详情页
                    detail_info = self._navigate_to_product_detail(product, main_window)
                    if detail_info:
                        # 合并列表页信息和详情页信息
                        combined_info = {**product, **detail_info}
                        detailed_products.append(combined_info)
                        
                        self.logger.info(f"✅ 第 {i} 个商品详情获取成功")
                        print(f"✅ 第 {i} 个商品详情获取完成")
                    else:
                        self.logger.warning(f"⚠️ 第 {i} 个商品详情获取失败")
                        print(f"⚠️ 第 {i} 个商品详情获取失败")
                    
                    sys.stdout.flush()
                    time.sleep(1)  # 避免请求过快
                    
                except Exception as e:
                    self.logger.error(f"处理第 {i} 个商品详情时出错: {e}")
                    print(f"❌ 第 {i} 个商品详情处理出错: {e}")
                    sys.stdout.flush()
                    continue
            
            self.logger.info(f"📋 商品详情获取完成，共 {len(detailed_products)} 个成功")
            print(f"📋 商品详情获取完成，共 {len(detailed_products)} 个成功")
            sys.stdout.flush()
            
            return detailed_products
            
        except Exception as e:
            self.logger.error(f"获取商品详情失败: {e}")
            print(f"❌ 获取商品详情失败: {e}")
            sys.stdout.flush()
            return []
    
    def _navigate_to_product_detail(self, product, main_window):
        """导航到商品详情页并提取详情信息"""
        try:
            # 首先确保只有一个主窗口是打开的
            current_windows = self.driver.window_handles
            if len(current_windows) > 1:
                self.logger.info(f"🔧 检测到 {len(current_windows)} 个窗口，清理多余窗口...")
                for window in current_windows:
                    if window != main_window:
                        try:
                            self.driver.switch_to.window(window)
                            self.driver.close()
                            self.logger.info(f"🗑️ 已关闭多余窗口: {window}")
                        except:
                            pass
                
                # 切换回主窗口
                self.driver.switch_to.window(main_window)
                time.sleep(1)
                self.logger.info("✅ 已切换回主窗口")
            
            card_element = product.get('card_element')
            if not card_element:
                self.logger.error("商品卡片元素不存在")
                return None
            
            # 滚动到卡片位置确保可见
            self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", card_element)
            time.sleep(1)
            
            # 尝试多种点击策略，优先点击能跳转到详情页的链接
            clicked = False
            
            # 策略1: 寻找并点击详情页链接
            try:
                # 先尝试寻找包含item.htm的直接链接
                detail_links = card_element.find_elements(By.CSS_SELECTOR, 'a[href*="item.htm"]')
                if detail_links:
                    detail_link = detail_links[0]
                    href = detail_link.get_attribute('href')
                    self.logger.info(f"找到商品详情链接: {href[:80]}...")
                    detail_link.click()
                    clicked = True
                else:
                    # 寻找其他可能的详情页链接
                    all_links = card_element.find_elements(By.CSS_SELECTOR, 'a')
                    self.logger.info(f"在商品卡片中找到 {len(all_links)} 个链接")
                    
                    for i, link in enumerate(all_links):
                        href = link.get_attribute('href')
                        if href:
                            self.logger.info(f"链接 {i+1}: {href[:80]}...")
                            if 'item' in href or 'detail' in href:
                                self.logger.info(f"尝试点击详情链接 {i+1}...")
                                link.click()
                                clicked = True
                                break
                    
                    # 如果没有找到明确的详情链接，尝试点击第一个链接
                    if not clicked and all_links:
                        first_link = all_links[0]
                        href = first_link.get_attribute('href')
                        self.logger.info(f"尝试点击第一个链接: {href[:80]}...")
                        first_link.click()
                        clicked = True
                        
            except Exception as e:
                self.logger.warning(f"点击详情链接失败: {e}")
            
            # 策略2: 点击商品图片（带链接的）
            if not clicked:
                try:
                    img_links = card_element.find_elements(By.CSS_SELECTOR, 'a img')
                    if img_links:
                        img_link = img_links[0].find_element(By.XPATH, '..')  # 获取父级a标签
                        if img_link and img_link.is_displayed():
                            self.logger.info("尝试点击商品图片链接...")
                            img_link.click()
                            clicked = True
                    else:
                        # 尝试直接点击图片
                        img_element = card_element.find_element(By.CSS_SELECTOR, 'img')
                        if img_element and img_element.is_displayed():
                            self.logger.info("尝试点击商品图片...")
                            img_element.click()
                            clicked = True
                except Exception as e:
                    self.logger.warning(f"点击图片失败: {e}")
            
            # 策略3: 点击商品标题
            if not clicked:
                try:
                    title_element = card_element.find_element(By.CSS_SELECTOR, self.config.SELECTORS['product_list']['product_title'])
                    if title_element and title_element.is_displayed():
                        self.logger.info("尝试点击商品标题...")
                        title_element.click()
                        clicked = True
                except Exception as e:
                    self.logger.warning(f"点击标题失败: {e}")
            
            # 策略4: 点击整个卡片
            if not clicked:
                try:
                    self.logger.info("尝试点击整个商品卡片...")
                    card_element.click()
                    clicked = True
                except Exception as e:
                    self.logger.warning(f"点击卡片失败: {e}")
            
            if not clicked:
                self.logger.error("所有点击策略都失败")
                return None
            
            # 等待新页面加载
            time.sleep(3)
            
            # 检查是否打开了新标签页
            current_windows = self.driver.window_handles
            if len(current_windows) > 1:
                # 切换到新标签页
                detail_window = None
                for window in current_windows:
                    if window != main_window:
                        detail_window = window
                        self.driver.switch_to.window(window)
                        self.logger.info("✅ 已切换到详情页标签")
                        break
                
                # 等待页面跳转到详情页（可能需要多次检查）
                detail_url = None
                for attempt in range(10):  # 最多等待10次，每次2秒
                    time.sleep(2)
                    current_url = self.driver.current_url
                    self.logger.info(f"尝试 {attempt + 1}/10: 当前URL: {current_url}")
                    
                    # 检查是否到达了商品详情页
                    if "item.htm" in current_url or "detail" in current_url:
                        detail_url = current_url
                        self.logger.info(f"✅ 成功跳转到商品详情页: {detail_url}")
                        break
                    elif "shop" in current_url and "taobao.com" in current_url:
                        # 如果还在店铺页面，继续等待
                        self.logger.info(f"⏳ 页面仍在跳转中，继续等待... ({current_url})")
                        continue
                    else:
                        # 其他未知页面
                        self.logger.warning(f"⚠️ 页面跳转到未知URL: {current_url}")
                        break
                
                # 检查最终是否成功跳转到详情页
                if detail_url and ("item.htm" in detail_url or "detail" in detail_url):
                    # 等待关键元素出现
                    try:
                        WebDriverWait(self.driver, 15).until(
                            lambda d: d.find_elements(By.CSS_SELECTOR, '.mainTitle--R75fTcZL, .highlightPrice--LlVWiXXs, .ItemTitle--n4_pxQxz, .generalParamsInfoItem--qLqLDVWp')
                        )
                        self.logger.info("✅ 详情页关键元素已加载")
                    except:
                        self.logger.warning("⚠️ 详情页关键元素加载超时，继续执行...")
                    
                    # 提取商品详情信息
                    detail_info = self._extract_product_detail()
                    
                    # 关闭详情页，回到主页面
                    self.driver.close()
                    self.driver.switch_to.window(main_window)
                    time.sleep(2)
                    
                    return detail_info
                else:
                    # 如果没有正确跳转到详情页，关闭当前窗口回到主页面
                    current_url = self.driver.current_url
                    self.logger.warning(f"⚠️ 未正确跳转到商品详情页，当前URL: {current_url}")
                    self.driver.close()
                    self.driver.switch_to.window(main_window)
                    time.sleep(1)
                    return None
            else:
                # 没有新标签页，可能是在当前页面打开
                # 检查URL是否变化
                current_url = self.driver.current_url
                self.logger.info(f"当前页面URL: {current_url}")
                
                if "item.taobao.com" in current_url or "detail.taobao.com" in current_url or "item.htm" in current_url:
                    # 等待详情页完全加载
                    time.sleep(5)
                    
                    # 等待关键元素出现
                    try:
                        WebDriverWait(self.driver, 15).until(
                            lambda d: d.find_elements(By.CSS_SELECTOR, '.mainTitle--R75fTcZL, .highlightPrice--LlVWiXXs, .ItemTitle--n4_pxQxz')
                        )
                        self.logger.info("✅ 详情页关键元素已加载")
                    except:
                        self.logger.warning("⚠️ 详情页关键元素加载超时，继续执行...")
                    
                    # 提取详情信息
                    detail_info = self._extract_product_detail()
                    
                    # 返回列表页
                    self.driver.back()
                    time.sleep(3)
                    
                    return detail_info
                else:
                    self.logger.warning(f"点击后页面未跳转到商品详情页，当前URL: {current_url}")
                    return None
            
        except Exception as e:
            self.logger.error(f"导航到商品详情页失败: {e}")
            # 确保回到主窗口
            try:
                self.driver.switch_to.window(main_window)
            except:
                pass
            return None
    
    def navigate_to_product_detail(self, product_url):
        """导航到商品详情页"""
        try:
            # TODO: 实现详情页导航逻辑
            return True
        except Exception as e:
            self.logger.error(f"导航到商品详情页失败: {e}")
            return False
    
    def _extract_product_detail(self):
        """提取商品详细信息"""
        try:
            self.logger.info("🔍 开始提取商品详情...")
            
            # 等待页面加载完成
            time.sleep(6)  # 增加等待时间确保页面完全加载
            
            detail_info = {
                'detail_url': self.driver.current_url,
                'detail_extracted': True
            }
            
            # 1. 提取商品标题
            detail_info.update(self._extract_product_title_detail())
            
            # 2. 提取价格信息
            detail_info.update(self._extract_price_detail())
            
            # 3. 提取参数信息
            detail_info.update(self._extract_params_info())
            
            # 4. 提取规格信息
            detail_info.update(self._extract_sku_info())
            
            # 5. 提取物流保障信息
            detail_info.update(self._extract_logistics_info())
            
            # 6. 提取优惠券信息
            detail_info.update(self._extract_coupon_info())
            
            # 7. 提取主图
            detail_info.update(self._extract_main_image())
            
            self.logger.info("✅ 商品详情提取完成")
            return detail_info
            
        except Exception as e:
            self.logger.error(f"提取商品详情失败: {e}")
            return {
                'detail_url': self.driver.current_url if hasattr(self, 'driver') else None,
                'detail_extracted': False,
                'error': str(e)
            }
    
    def extract_product_detail(self, product_basic_info):
        """提取商品详情信息 (保持兼容性)"""
        return self._extract_product_detail()
    
    def _extract_product_title_detail(self):
        """提取商品标题"""
        try:
            selectors = [
                '.mainTitle--R75fTcZL',
                '.MainTitle--PiA4nmJz .mainTitle--R75fTcZL',
                '[title*="舞"] span',
                '.ItemTitle--n4_pxQxz span'
            ]
            
            for selector in selectors:
                try:
                    element = self.driver.find_element(By.CSS_SELECTOR, selector)
                    title = element.get_attribute('title') or element.text.strip()
                    if title:
                        self.logger.info(f"✅ 提取到商品标题: {title[:50]}...")
                        return {'product_title': title}
                except:
                    continue
            
            self.logger.warning("⚠️ 未找到商品标题")
            return {'product_title': ''}
            
        except Exception as e:
            self.logger.error(f"提取商品标题失败: {e}")
            return {'product_title': ''}
    
    def _extract_price_detail(self):
        """提取价格信息"""
        try:
            price_info = {}
            
            # 券后价格 - 多策略精确定位
            try:
                # 策略1：查找所有可能的价格容器
                price_containers = self.driver.find_elements(By.CSS_SELECTOR, 
                    '.highlightPrice--LlVWiXXs, .priceWrap--R3TrPIS6 .highlightPrice--LlVWiXXs, .normalPrice--BXrHJ8Qk .highlightPrice--LlVWiXXs')
                self.logger.info(f"🔍 找到 {len(price_containers)} 个价格容器")
                
                coupon_price_found = False
                
                # 遍历所有价格容器，找到有内容的那个
                for container_idx, price_container in enumerate(price_containers):
                    self.logger.info(f"🔍 检查价格容器 {container_idx + 1}")
                    
                    # 方法1：通过span元素索引
                    highlight_spans = price_container.find_elements(By.TAG_NAME, 'span')
                    self.logger.info(f"  容器内找到 {len(highlight_spans)} 个span元素")
                    
                    for i, span in enumerate(highlight_spans):
                        span_text = span.text.strip()
                        span_class = span.get_attribute('class')
                        self.logger.info(f"    Span {i+1}: '{span_text}' (class: {span_class})")
                    
                    # 寻找有内容的价格span
                    for span in highlight_spans:
                        span_text = span.text.strip()
                        span_class = span.get_attribute('class') or ''
                        
                        # 如果是价格数字类且有内容
                        if 'text--LP7Wf49z' in span_class and span_text and span_text.replace('.', '').replace(',', '').isdigit():
                            price_info['coupon_price'] = f"¥{span_text}"
                            self.logger.info(f"✅ 券后价(容器{container_idx + 1}): {price_info['coupon_price']}")
                            coupon_price_found = True
                            break
                    
                    if coupon_price_found:
                        break
                
                # 策略2：如果容器方法失败，直接在整个页面搜索
                if not coupon_price_found:
                    self.logger.info("🔍 容器方法失败，尝试全页面搜索...")
                    
                    # 查找所有包含价格数字的text元素
                    all_price_elements = self.driver.find_elements(By.CSS_SELECTOR, '.text--LP7Wf49z')
                    self.logger.info(f"🔍 全页面找到 {len(all_price_elements)} 个价格元素")
                    
                    for i, element in enumerate(all_price_elements):
                        element_text = element.text.strip()
                        self.logger.info(f"  价格元素 {i+1}: '{element_text}'")
                        
                        if element_text and element_text.replace('.', '').replace(',', '').isdigit():
                            # 检查父级元素是否为券后价格
                            parent = element.find_element(By.XPATH, '..')
                            parent_class = parent.get_attribute('class') or ''
                            
                            if 'highlightPrice' in parent_class:
                                price_info['coupon_price'] = f"¥{element_text}"
                                self.logger.info(f"✅ 券后价(全页面搜索): {price_info['coupon_price']}")
                                coupon_price_found = True
                                break
                
                if not coupon_price_found:
                    price_info['coupon_price'] = ''
                    self.logger.warning("⚠️ 所有方法都未找到券后价格")
                    
            except Exception as e:
                price_info['coupon_price'] = ''
                self.logger.warning(f"⚠️ 券后价格提取异常: {e}")
            
            # 优惠前价格 - 多策略精确定位
            try:
                # 策略1：查找所有可能的原价容器
                original_price_containers = self.driver.find_elements(By.CSS_SELECTOR, 
                    '.subPrice--KfQ0yn4v, .normalPrice--BXrHJ8Qk .subPrice--KfQ0yn4v')
                self.logger.info(f"🔍 找到 {len(original_price_containers)} 个原价容器")
                
                original_price_found = False
                
                # 遍历所有原价容器，找到有内容的那个
                for container_idx, price_container in enumerate(original_price_containers):
                    self.logger.info(f"🔍 检查原价容器 {container_idx + 1}")
                    
                    sub_price_spans = price_container.find_elements(By.TAG_NAME, 'span')
                    self.logger.info(f"  容器内找到 {len(sub_price_spans)} 个span元素")
                    
                    for i, span in enumerate(sub_price_spans):
                        span_text = span.text.strip()
                        span_class = span.get_attribute('class')
                        self.logger.info(f"    Span {i+1}: '{span_text}' (class: {span_class})")
                    
                    # 寻找有内容的价格span（第3个通常是价格数字）
                    if len(sub_price_spans) >= 3:
                        price_text = sub_price_spans[2].text.strip()
                        if price_text and price_text.replace('.', '').replace(',', '').isdigit():
                            price_info['original_price'] = f"¥{price_text}"
                            self.logger.info(f"✅ 优惠前价(容器{container_idx + 1}): {price_info['original_price']}")
                            original_price_found = True
                            break
                    
                    # 备用：寻找任何包含数字的text span
                    for span in sub_price_spans:
                        span_text = span.text.strip()
                        span_class = span.get_attribute('class') or ''
                        
                        if 'text--LP7Wf49z' in span_class and span_text and span_text.replace('.', '').replace(',', '').isdigit():
                            price_info['original_price'] = f"¥{span_text}"
                            self.logger.info(f"✅ 优惠前价(备用方法): {price_info['original_price']}")
                            original_price_found = True
                            break
                    
                    if original_price_found:
                        break
                
                # 策略2：如果容器方法失败，直接在整个页面搜索第二个价格
                if not original_price_found:
                    self.logger.info("🔍 原价容器方法失败，尝试全页面搜索...")
                    
                    # 查找所有包含价格数字的text元素
                    all_price_elements = self.driver.find_elements(By.CSS_SELECTOR, '.text--LP7Wf49z')
                    price_count = 0
                    
                    for element in all_price_elements:
                        element_text = element.text.strip()
                        
                        if element_text and element_text.replace('.', '').replace(',', '').isdigit():
                            price_count += 1
                            self.logger.info(f"  找到第{price_count}个价格: {element_text}")
                            
                            # 第二个找到的价格通常是原价
                            if price_count == 2:
                                price_info['original_price'] = f"¥{element_text}"
                                self.logger.info(f"✅ 优惠前价(全页面搜索): {price_info['original_price']}")
                                original_price_found = True
                                break
                
                if not original_price_found:
                    price_info['original_price'] = ''
                    self.logger.warning("⚠️ 所有方法都未找到优惠前价格")
                    
            except Exception as e:
                price_info['original_price'] = ''
                self.logger.warning(f"⚠️ 优惠前价格提取异常: {e}")
            
            # 销量 - 精确定位
            try:
                sales_element = self.driver.find_element(By.CSS_SELECTOR, '.salesDesc--Z35wP98o')
                sales_text = sales_element.text.strip()
                # 去掉前面的点号，只保留销量文字
                if sales_text and sales_text.startswith('·'):
                    sales_text = sales_text[1:].strip()
                
                if sales_text:
                    price_info['sales'] = sales_text
                    self.logger.info(f"✅ 销量信息: {sales_text}")
                else:
                    price_info['sales'] = ''
                    self.logger.warning("⚠️ 销量信息为空")
            except Exception as e:
                price_info['sales'] = ''
                self.logger.warning(f"⚠️ 未找到销量信息: {e}")
            
            return price_info
            
        except Exception as e:
            self.logger.error(f"提取价格信息失败: {e}")
            return {'coupon_price': '', 'original_price': '', 'sales': ''}
    
    def _extract_params_info(self):
        """提取参数信息"""
        try:
            params = {}
            
            # 查找参数信息区域
            try:
                # 尝试滚动到参数信息区域
                try:
                    param_tab = self.driver.find_element(By.CSS_SELECTOR, '[data-tabindex="1"]')
                    if param_tab:
                        self.driver.execute_script("arguments[0].scrollIntoView();", param_tab)
                        time.sleep(2)
                except:
                    self.logger.info("未找到参数信息标签，尝试直接查找参数元素...")
                    time.sleep(1)
                
                param_items = self.driver.find_elements(By.CSS_SELECTOR, '.generalParamsInfoItem--qLqLDVWp')
                
                for item in param_items:
                    try:
                        title_element = item.find_element(By.CSS_SELECTOR, '.generalParamsInfoItemTitle--Fo9kKj5Z')
                        value_element = item.find_element(By.CSS_SELECTOR, '.generalParamsInfoItemSubTitle--S4pgp6b9')
                        
                        title = title_element.get_attribute('title') or title_element.text.strip()
                        value = value_element.get_attribute('title') or value_element.text.strip()
                        
                        if title and value:
                            params[title] = value
                    except:
                        continue
                
                self.logger.info(f"✅ 提取到 {len(params)} 个参数信息")
                return {'params_info': params}
                
            except Exception as e:
                self.logger.warning(f"提取参数信息失败: {e}")
                return {'params_info': {}}
            
        except Exception as e:
            self.logger.error(f"提取参数信息失败: {e}")
            return {'params_info': {}}
    
    def _extract_sku_info(self):
        """提取规格信息"""
        try:
            sku_info = {}
            
            # 提取规格选项
            sku_items = self.driver.find_elements(By.CSS_SELECTOR, '.skuItem--Z2AJB9Ew')
            
            for sku_item in sku_items:
                try:
                    # 规格名称（如：颜色分类、鞋码）
                    label_element = sku_item.find_element(By.CSS_SELECTOR, '.ItemLabel--psS1SOyC span')
                    label = label_element.get_attribute('title') or label_element.text.strip()
                    
                    # 规格选项值
                    value_elements = sku_item.find_elements(By.CSS_SELECTOR, '.valueItem--smR4pNt4 span')
                    values = []
                    
                    for value_element in value_elements:
                        value = value_element.get_attribute('title') or value_element.text.strip()
                        if value:
                            values.append(value)
                    
                    if label and values:
                        sku_info[label] = values
                        
                except:
                    continue
            
            self.logger.info(f"✅ 提取到 {len(sku_info)} 个规格类型")
            return {'sku_info': sku_info}
            
        except Exception as e:
            self.logger.error(f"提取规格信息失败: {e}")
            return {'sku_info': {}}
    
    def _extract_logistics_info(self):
        """提取物流保障信息"""
        try:
            logistics_info = {}
            
            # 物流信息
            try:
                shipping_element = self.driver.find_element(By.CSS_SELECTOR, '.shipping--Obxoxza7')
                shipping = shipping_element.text.strip()
                logistics_info['shipping_time'] = shipping
            except:
                logistics_info['shipping_time'] = ''
            
            try:
                freight_element = self.driver.find_element(By.CSS_SELECTOR, '.freight--oatKHK1s')
                freight = freight_element.text.strip()
                logistics_info['freight'] = freight
            except:
                logistics_info['freight'] = ''
            
            try:
                addr_element = self.driver.find_element(By.CSS_SELECTOR, '.deliveryAddrWrap--KgrR00my span')
                addr = addr_element.text.strip()
                logistics_info['delivery_addr'] = addr
            except:
                logistics_info['delivery_addr'] = ''
            
            # 保障信息
            guarantee_list = []
            try:
                guarantee_elements = self.driver.find_elements(By.CSS_SELECTOR, '.guaranteeText--hqmmjLTB')
                for element in guarantee_elements:
                    text = element.text.strip()
                    if text:
                        guarantee_list.append(text)
            except:
                pass
            
            logistics_info['guarantees'] = guarantee_list
            
            self.logger.info(f"✅ 提取物流保障信息完成")
            return {'logistics_info': logistics_info}
            
        except Exception as e:
            self.logger.error(f"提取物流保障信息失败: {e}")
            return {'logistics_info': {}}
    
    def _extract_coupon_info(self):
        """提取优惠券信息"""
        try:
            coupons = []
            
            coupon_elements = self.driver.find_elements(By.CSS_SELECTOR, '.couponText--XuXNjizk')
            
            for element in coupon_elements:
                coupon_text = element.get_attribute('title') or element.text.strip()
                if coupon_text:
                    coupons.append(coupon_text)
            
            self.logger.info(f"✅ 提取到 {len(coupons)} 个优惠券")
            return {'coupons': coupons}
            
        except Exception as e:
            self.logger.error(f"提取优惠券信息失败: {e}")
            return {'coupons': []}
    
    def _extract_main_image(self):
        """提取主图"""
        try:
            image_selectors = [
                '.mainPic--zxTtQs0P',
                '.picGallery--qY53_w0u img',
                '.thumbnailActive--JUfZQotF img'
            ]
            
            for selector in image_selectors:
                try:
                    element = self.driver.find_element(By.CSS_SELECTOR, selector)
                    src = element.get_attribute('src') or element.get_attribute('data-src')
                    
                    if src and 'http' in src:
                        self.logger.info(f"✅ 提取到主图: {src[:50]}...")
                        return {'main_image': src}
                except:
                    continue
            
            self.logger.warning("⚠️ 未找到主图")
            return {'main_image': ''}
            
        except Exception as e:
            self.logger.error(f"提取主图失败: {e}")
            return {'main_image': ''}
    
    def _extract_product_title(self):
        """提取商品标题 (兼容性方法)"""
        result = self._extract_product_title_detail()
        return result.get('product_title', '')
    
    def _extract_product_price(self):
        """提取商品价格 (兼容性方法)"""
        return self._extract_price_detail()
    
    def _extract_product_images(self):
        """提取商品图片 (兼容性方法)"""
        result = self._extract_main_image()
        main_image = result.get('main_image', '')
        return [main_image] if main_image else []
    
    def _extract_product_description(self):
        """提取商品描述 (兼容性方法)"""
        # 商品描述可以从参数信息中构建
        params_result = self._extract_params_info()
        params = params_result.get('params_info', {})
        
        description_parts = []
        for key, value in params.items():
            description_parts.append(f"{key}: {value}")
        
        return "; ".join(description_parts)
    
    def _extract_product_specifications(self):
        """提取商品规格 (兼容性方法)"""
        return self._extract_sku_info()
    
    def _extract_shop_info(self):
        """提取店铺信息"""
        try:
            shop_info = {}
            
            # 店铺名称
            try:
                shop_name_element = self.driver.find_element(By.CSS_SELECTOR, '.shopName--cSjM9uKk')
                shop_name = shop_name_element.get_attribute('title') or shop_name_element.text.strip()
                shop_info['shop_name'] = shop_name
            except:
                shop_info['shop_name'] = ''
            
            return shop_info
            
        except Exception as e:
            self.logger.error(f"提取店铺信息失败: {e}")
            return {}
    
    # ==================== 数据处理和保存 ====================
    
    def save_products_data(self, products, filename=None):
        """保存商品数据"""
        try:
            if not filename:
                filename = self.config.PRODUCT_LIST_FILE
            
            filepath = os.path.join(self.config.OUTPUT_DIR, filename)
            with open(filepath, 'w', encoding='utf-8') as f:
                json.dump(products, f, ensure_ascii=False, indent=2)
            
            self.logger.info(f"商品数据已保存到: {filepath}")
            return True
            
        except Exception as e:
            self.logger.error(f"保存商品数据失败: {e}")
            return False
    
    def convert_to_api_format(self, product):
        """转换为API格式"""
        try:
            # 提取基本信息
            title = product.get('product_title', product.get('title', ''))
            detail_url = product.get('detail_url', '')
            main_image = product.get('main_image', product.get('image_url', ''))
            
            # 构建product_data字符串
            product_data_parts = []
            
            # 添加价格信息
            coupon_price = product.get('coupon_price', '')
            original_price = product.get('original_price', '')
            sales = product.get('sales', '')
            
            if coupon_price:
                product_data_parts.append(f"券后价: {coupon_price}")
            if original_price:
                product_data_parts.append(f"优惠前: {original_price}")
            if sales:
                product_data_parts.append(f"销量: {sales}")
            
            # 添加参数信息
            params_info = product.get('params_info', {})
            for key, value in params_info.items():
                product_data_parts.append(f"{key}: {value}")
            
            # 添加规格信息
            sku_info = product.get('sku_info', {})
            for sku_name, sku_values in sku_info.items():
                if isinstance(sku_values, list):
                    sku_str = ",".join(sku_values)
                else:
                    sku_str = str(sku_values)
                product_data_parts.append(f"{sku_name}: {sku_str}")
            
            # 添加物流保障信息
            logistics_info = product.get('logistics_info', {})
            if logistics_info.get('shipping_time'):
                product_data_parts.append(f"发货时间: {logistics_info['shipping_time']}")
            if logistics_info.get('freight'):
                product_data_parts.append(f"运费: {logistics_info['freight']}")
            if logistics_info.get('delivery_addr'):
                product_data_parts.append(f"发货地: {logistics_info['delivery_addr']}")
            
            guarantees = logistics_info.get('guarantees', [])
            if guarantees:
                product_data_parts.append(f"保障: {','.join(guarantees)}")
            
            # 添加优惠券信息
            coupons = product.get('coupons', [])
            if coupons:
                product_data_parts.append(f"优惠券: {','.join(coupons)}")
            
            # 提取商品ID (从URL中提取)
            product_id = ''
            if detail_url:
                import re
                # 尝试从URL中提取商品ID
                id_match = re.search(r'id=(\d+)', detail_url)
                if id_match:
                    product_id = id_match.group(1)
                else:
                    # 尝试其他模式
                    id_match = re.search(r'/(\d+)\.html', detail_url)
                    if id_match:
                        product_id = id_match.group(1)
            
            # 提取品牌作为product_type
            product_type = ''
            if params_info.get('品牌'):
                product_type = params_info['品牌']
            elif '品牌' in str(product_data_parts):
                # 从product_data中提取品牌
                for part in product_data_parts:
                    if part.startswith('品牌:'):
                        product_type = part.split(':', 1)[1].strip()
                        break
            
            api_data = {
                "home_image": main_image,
                "product_name": title,
                "product_type": product_type,
                "product_data": "; ".join(product_data_parts),
                "product_url": detail_url,
                "platform_product_id": product_id
            }
            
            return api_data
            
        except Exception as e:
            self.logger.error(f"转换API格式失败: {e}")
            return None
    
    def submit_to_api(self, products: List[Dict[str, Any]], store_id: str) -> bool:
        """提交数据到API"""
        try:
            # 导入API配置
            import sys
            import os
            sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
            from api_config import APIConfig
            
            # 获取API配置
            api_url = APIConfig.get_products_api_url()
            
            if APIConfig.ENABLE_REQUEST_LOGGING:
                # 打印原始提取的商品数据
                print("\n" + "="*80)
                print("📦 TaoBao原始提取的商品数据:")
                print("="*80)
                for i, product in enumerate(products, 1):
                    print(f"\n🔍 原始商品 {i} 数据:")
                    for key, value in product.items():
                        if key == 'element':
                            continue  # 跳过WebElement对象
                        if isinstance(value, str) and len(value) > 100:
                            print(f"  {key}: {value[:100]}...")
                        else:
                            print(f"  {key}: {value}")
                print("="*80)
            
            # 直接使用传入的API格式数据（GUI监听器已经转换过了）
            api_products = products
            
            # 构建请求数据
            payload = {
                "store_id": store_id,
                "platform": APIConfig.PLATFORM_MAPPING.get("淘宝", "TaoBao"),
                "products": api_products
            }
            
            if APIConfig.ENABLE_REQUEST_LOGGING:
                # 打印详细的API数据到控制台
                print("\n" + "="*80)
                print("🚀 TaoBao准备提交到API的数据详情:")
                print("="*80)
                print(f"📋 Store ID: {store_id}")
                print(f"🏪 Platform: {APIConfig.PLATFORM_MAPPING.get('淘宝', 'TaoBao')}")
                print(f"📦 商品数量: {len(api_products)}")
                print(f"🌐 API地址: {api_url}")
                print("-"*80)
                
                for i, product in enumerate(api_products, 1):
                    print(f"\n📦 商品 {i}:")
                    print(f"  🏷️  商品名称: {product.get('product_name', 'N/A')}")
                    print(f"  🆔 商品ID: {product.get('platform_product_id', 'N/A')}")
                    # 从product_data字符串中提取价格
                    product_data_str = product.get('product_data', '')
                    price = 'N/A'
                    if isinstance(product_data_str, str) and '券后价:' in product_data_str:
                        try:
                            # 从字符串中提取价格信息
                            import re
                            price_match = re.search(r'券后价:\s*([^;]+)', product_data_str)
                            if price_match:
                                price = price_match.group(1).strip()
                        except:
                            pass
                    print(f"  💰 价格: {price}")
                    print(f"  🖼️  封面图: {product.get('home_image', 'N/A')[:80]}{'...' if len(str(product.get('home_image', ''))) > 80 else ''}")
                    print(f"  🔗 商品链接: {product.get('product_url', 'N/A')}")
                
                print("="*80)
                print("🔄 开始提交到API...")
                print("="*80)

            # 发送请求（支持重试）
            import requests
            import time
            
            for attempt in range(APIConfig.MAX_RETRIES):
                try:
                    if APIConfig.ENABLE_VERBOSE_LOGGING:
                        print(f"🔄 第 {attempt + 1}/{APIConfig.MAX_RETRIES} 次尝试提交...")
                    
                    response = requests.post(
                        api_url,
                        json=payload,
                        headers=APIConfig.DEFAULT_HEADERS,
                        timeout=APIConfig.REQUEST_TIMEOUT
                    )
                    
                    if APIConfig.ENABLE_RESPONSE_LOGGING:
                        print(f"📡 API响应状态码: {response.status_code}")
                        if response.text:
                            print(f"📄 API响应内容: {response.text[:500]}...")
                    
                    if response.status_code == 200:
                        print(f"✅ TaoBao API提交成功: {len(api_products)} 个商品")
                        self.logger.info(f"TaoBao API提交成功: store_id={store_id}, 商品数={len(api_products)}")
                        return True
                    else:
                        error_msg = f"API返回错误状态码: {response.status_code}"
                        if response.text:
                            error_msg += f" - {response.text}"
                        
                        if attempt < APIConfig.MAX_RETRIES - 1:
                            print(f"⚠️ {error_msg}，{APIConfig.RETRY_DELAY}秒后重试...")
                            time.sleep(APIConfig.RETRY_DELAY)
                        else:
                            print(f"❌ TaoBao API提交失败: {error_msg}")
                            self.logger.error(f"TaoBao API提交失败: {error_msg}")
                            return False
                            
                except requests.RequestException as e:
                    error_msg = f"网络请求异常: {e}"
                    if attempt < APIConfig.MAX_RETRIES - 1:
                        print(f"⚠️ {error_msg}，{APIConfig.RETRY_DELAY}秒后重试...")
                        time.sleep(APIConfig.RETRY_DELAY)
                    else:
                        print(f"❌ TaoBao API提交失败: {error_msg}")
                        self.logger.error(f"TaoBao API提交失败: {error_msg}")
                        return False
            
            return False
                
        except Exception as e:
            self.logger.error(f"TaoBao API提交异常: {e}")
            print(f"❌ TaoBao API提交异常: {e}")
            return False
    
    def print_api_format_data(self, products):
        """打印API格式数据"""
        try:
            api_products = []
            for product in products:
                api_data = self.convert_to_api_format(product)
                if api_data:
                    api_products.append(api_data)
            
            # 保存API格式数据
            api_filepath = os.path.join(self.config.OUTPUT_DIR, self.config.API_FORMAT_FILE)
            with open(api_filepath, 'w', encoding='utf-8') as f:
                json.dump(api_products, f, ensure_ascii=False, indent=2)
            
            self.logger.info(f"API格式数据已保存到: {api_filepath}")
            
            # 打印预览
            if api_products:
                print("\n" + "="*80)
                print("🎯 TaoBao商品API格式预览")
                print("="*80)
                for i, product in enumerate(api_products[:3], 1):
                    print(f"\n📦 商品 {i}:")
                    for key, value in product.items():
                        print(f"  {key}: {value}")
                print(f"\n✅ 总计 {len(api_products)} 个商品已转换为API格式")
            
        except Exception as e:
            self.logger.error(f"打印API格式数据失败: {e}")
    
    # ==================== 辅助方法 ====================
    
    def wait_for_element(self, selector, timeout=None):
        """等待元素出现"""
        try:
            timeout = timeout or self.config.DEFAULT_TIMEOUT
            element = WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, selector))
            )
            return element
        except TimeoutException:
            self.logger.warning(f"等待元素超时: {selector}")
            return None
    
    def safe_click(self, element):
        """安全点击元素"""
        try:
            self.driver.execute_script("arguments[0].click();", element)
            return True
        except Exception as e:
            self.logger.error(f"点击元素失败: {e}")
            return False
    
    def scroll_to_element(self, element):
        """滚动到元素"""
        try:
            self.driver.execute_script("arguments[0].scrollIntoView(true);", element)
            time.sleep(1)
        except Exception as e:
            self.logger.error(f"滚动到元素失败: {e}")
    
    def _simulate_human_typing(self, element, text: str, typing_speed: float = 0.1):
        """模拟人工逐字符输入"""
        try:
            self.logger.info(f"🤖 开始模拟人工输入 {len(text)} 个字符...")
            element.clear()
            time.sleep(0.5)  # 清空后稍等
            
            for i, char in enumerate(text):
                element.send_keys(char)
                # 随机延迟，模拟真实打字速度
                import random
                delay = typing_speed + random.uniform(-0.05, 0.1)
                time.sleep(max(0.05, delay))  # 最小延迟50ms
                
                # 每输入几个字符暂停一下，模拟思考
                if (i + 1) % 3 == 0:
                    time.sleep(random.uniform(0.1, 0.3))
            
            self.logger.info("✅ 人工模拟输入完成")
            return True
            
        except Exception as e:
            self.logger.error(f"❌ 模拟输入失败: {e}")
            return False

    def _fill_login_form(self, username, password):
        """人工模拟填写登录表单"""
        try:
            self.logger.info("开始填写登录表单...")
            print("🤖 开始自动填写登录表单...")
            sys.stdout.flush()
            
            # 等待页面完全加载
            time.sleep(3)
            
            # 等待并查找用户名输入框
            self.logger.info("🔍 查找用户名输入框...")
            username_input = self.wait_for_element(self.config.SELECTORS['login']['username_input'], timeout=10)
            if not username_input:
                # 尝试备选选择器
                username_inputs = self.driver.find_elements(By.CSS_SELECTOR, "input[placeholder*='账号'], input[placeholder*='手机号'], input[name*='login']")
                if username_inputs:
                    username_input = username_inputs[0]
                    self.logger.info("✅ 通过备选选择器找到用户名输入框")
                else:
                    self.logger.error("❌ 未找到用户名输入框")
                    return False
            else:
                self.logger.info("✅ 找到用户名输入框")
            
            # 模拟人工输入用户名
            try:
                print(f"🤖 正在逐字符输入用户名...")
                sys.stdout.flush()
                
                if self._simulate_human_typing(username_input, username, typing_speed=0.15):
                    self.logger.info(f"✅ 已输入用户名: {username[:3]}***")
                    print(f"✅ 用户名输入完成")
                    sys.stdout.flush()
                else:
                    self.logger.error("❌ 用户名模拟输入失败")
                    return False
            except Exception as e:
                self.logger.error(f"输入用户名失败: {e}")
                return False
            
            time.sleep(1)
            
            # 等待并查找密码输入框
            self.logger.info("🔍 查找密码输入框...")
            password_input = self.wait_for_element(self.config.SELECTORS['login']['password_input'], timeout=10)
            if not password_input:
                # 尝试备选选择器
                password_inputs = self.driver.find_elements(By.CSS_SELECTOR, "input[type='password'], input[placeholder*='密码']")
                if password_inputs:
                    password_input = password_inputs[0]
                    self.logger.info("✅ 通过备选选择器找到密码输入框")
                else:
                    self.logger.error("❌ 未找到密码输入框")
                    return False
            else:
                self.logger.info("✅ 找到密码输入框")
            
            # 模拟人工输入密码
            try:
                print(f"🤖 正在逐字符输入密码...")
                sys.stdout.flush()
                
                if self._simulate_human_typing(password_input, password, typing_speed=0.12):
                    self.logger.info("✅ 已输入密码")
                    print(f"✅ 密码输入完成")
                    sys.stdout.flush()
                else:
                    self.logger.error("❌ 密码模拟输入失败")
                    return False
            except Exception as e:
                self.logger.error(f"输入密码失败: {e}")
                return False
            
            time.sleep(1)
            
            # 检查是否需要勾选协议复选框
            self.logger.info("🔍 查找协议复选框...")
            print("📋 检查协议复选框...")
            sys.stdout.flush()
            
            # 等待协议区域加载
            time.sleep(1)
            
            agreement_checkboxes = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['agreement_checkbox'])
            if agreement_checkboxes:
                checkbox = agreement_checkboxes[0]
                try:
                    # 先检查复选框是否可见和可操作
                    if not checkbox.is_displayed():
                        self.logger.warning("⚠️ 协议复选框不可见")
                        print("⚠️ 协议复选框不可见")
                        sys.stdout.flush()
                    
                    if not checkbox.is_enabled():
                        self.logger.warning("⚠️ 协议复选框不可操作")
                        print("⚠️ 协议复选框不可操作")
                        sys.stdout.flush()
                    
                    # 滚动到复选框位置确保可见
                    self.driver.execute_script("arguments[0].scrollIntoView(true);", checkbox)
                    time.sleep(0.5)
                    
                    if not checkbox.is_selected():
                        self.logger.info("📋 勾选协议复选框...")
                        print("📋 正在勾选用户协议...")
                        sys.stdout.flush()
                        
                        # 方法1: 使用JavaScript点击
                        try:
                            self.driver.execute_script("arguments[0].click();", checkbox)
                            time.sleep(1)
                            
                            if checkbox.is_selected():
                                self.logger.info("✅ 通过JavaScript勾选协议成功")
                                print("✅ 协议勾选成功 (JavaScript)")
                                sys.stdout.flush()
                            else:
                                raise Exception("JavaScript点击后仍未勾选")
                        except Exception as js_e:
                            self.logger.warning(f"JavaScript点击失败: {js_e}")
                            
                            # 方法2: 直接点击复选框
                            try:
                                checkbox.click()
                                time.sleep(1)
                                
                                if checkbox.is_selected():
                                    self.logger.info("✅ 直接点击勾选协议成功")
                                    print("✅ 协议勾选成功 (直接点击)")
                                    sys.stdout.flush()
                                else:
                                    raise Exception("直接点击后仍未勾选")
                            except Exception as click_e:
                                self.logger.warning(f"直接点击失败: {click_e}")
                                
                                # 方法3: 点击协议标签
                                agreement_labels = self.driver.find_elements(By.CSS_SELECTOR, 'label[for="fm-agreement-checkbox"], .fm-agreement-text')
                                if agreement_labels:
                                    try:
                                        agreement_labels[0].click()
                                        time.sleep(1)
                                        
                                        if checkbox.is_selected():
                                            self.logger.info("✅ 通过标签勾选协议成功")
                                            print("✅ 协议勾选成功 (标签点击)")
                                            sys.stdout.flush()
                                        else:
                                            self.logger.warning("⚠️ 所有方法都无法勾选协议")
                                            print("⚠️ 无法自动勾选协议，后续可能出现弹框")
                                            sys.stdout.flush()
                                    except Exception as label_e:
                                        self.logger.error(f"标签点击失败: {label_e}")
                                        print("⚠️ 无法自动勾选协议，后续可能出现弹框")
                                        sys.stdout.flush()
                                else:
                                    self.logger.warning("⚠️ 未找到协议标签")
                                    print("⚠️ 无法自动勾选协议，后续可能出现弹框")
                                    sys.stdout.flush()
                    else:
                        self.logger.info("✅ 协议已勾选")
                        print("✅ 协议已经勾选")
                        sys.stdout.flush()
                except Exception as e:
                    self.logger.error(f"协议处理过程出错: {e}")
                    print("⚠️ 协议处理出错，后续可能出现弹框")
                    sys.stdout.flush()
            else:
                self.logger.info("ℹ️ 未找到协议复选框")
                print("ℹ️ 未找到协议复选框，后续可能出现弹框")
                sys.stdout.flush()
            
            # 自动点击登录按钮
            time.sleep(1)  # 确保协议勾选完成
            self.logger.info("🔍 查找登录按钮...")
            print("🔘 准备点击登录按钮...")
            sys.stdout.flush()
            
            submit_buttons = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['submit_button'])
            if submit_buttons:
                submit_button = submit_buttons[0]
                try:
                    self.logger.info("🔘 点击登录按钮...")
                    print("🔘 正在点击登录按钮...")
                    sys.stdout.flush()
                    
                    submit_button.click()
                    time.sleep(2)
                    
                    self.logger.info("✅ 已点击登录按钮")
                    print("✅ 登录按钮已点击")
                    sys.stdout.flush()
                    
                    # 检查是否出现协议弹框
                    self._handle_agreement_dialog()
                except Exception as e:
                    self.logger.error(f"点击登录按钮失败: {e}")
                    print("⚠️ 自动点击登录按钮失败，请手动点击")
                    sys.stdout.flush()
            else:
                self.logger.warning("⚠️ 未找到登录按钮，需要手动点击")
                print("⚠️ 未找到登录按钮，请手动点击")
                sys.stdout.flush()
            
            return True
            
        except Exception as e:
            self.logger.error(f"填写登录表单失败: {e}")
            print(f"❌ 自动填写失败: {e}")
            sys.stdout.flush()
            return False
    
    def _handle_agreement_dialog(self):
        """处理登录后可能出现的协议确认弹框"""
        try:
            self.logger.info("🔍 检查是否出现协议弹框...")
            print("🔍 检查协议弹框...")
            sys.stdout.flush()
            
            # 等待可能的弹框加载
            time.sleep(2)
            
            # 查找协议弹框
            dialog_selectors = [
                '.login-dialog',  # 主弹框容器
                'div[role="document"].login-dialog',  # 带role属性的弹框
                '.login-dialog-content',  # 弹框内容
                '[class*="dialog"][class*="login"]'  # 包含dialog和login的类名
            ]
            
            dialog_found = False
            for selector in dialog_selectors:
                dialogs = self.driver.find_elements(By.CSS_SELECTOR, selector)
                if dialogs and dialogs[0].is_displayed():
                    dialog_found = True
                    self.logger.info(f"✅ 发现协议弹框: {selector}")
                    print("📋 发现协议确认弹框")
                    sys.stdout.flush()
                    break
            
            if dialog_found:
                # 查找弹框标题确认是协议相关
                title_elements = self.driver.find_elements(By.CSS_SELECTOR, '.login-dialog-title, [id*="DialogTitle"]')
                if title_elements:
                    title_text = title_elements[0].text
                    self.logger.info(f"弹框标题: {title_text}")
                    if "协议" in title_text or "隐私" in title_text or "服务" in title_text:
                        self.logger.info("✅ 确认为协议相关弹框")
                        print(f"📋 协议弹框标题: {title_text}")
                        sys.stdout.flush()
                        
                        # 查找同意按钮
                        agree_button_selectors = [
                            '.dialog-btn-ok',  # 主要选择器
                            'button.dialog-btn-ok',  # 明确的按钮选择器
                            '.login-dialog-footer button:last-child',  # 弹框底部最后一个按钮
                            'button:contains("同意")',  # 包含"同意"文本的按钮
                            '.auth-agreement button[class*="ok"]'  # 协议区域的确认按钮
                        ]
                        
                        agree_clicked = False
                        for selector in agree_button_selectors:
                            try:
                                if selector == 'button:contains("同意")':
                                    # 使用XPath查找包含"同意"文本的按钮
                                    agree_buttons = self.driver.find_elements(By.XPATH, '//button[contains(text(), "同意")]')
                                else:
                                    agree_buttons = self.driver.find_elements(By.CSS_SELECTOR, selector)
                                
                                if agree_buttons and agree_buttons[0].is_displayed():
                                    self.logger.info(f"🔘 点击同意按钮: {selector}")
                                    print("🔘 正在点击同意按钮...")
                                    sys.stdout.flush()
                                    
                                    # 尝试点击同意按钮
                                    try:
                                        agree_buttons[0].click()
                                        time.sleep(1)
                                        
                                        # 验证弹框是否关闭
                                        if not dialogs[0].is_displayed():
                                            self.logger.info("✅ 协议弹框已关闭")
                                            print("✅ 协议确认成功")
                                            sys.stdout.flush()
                                            agree_clicked = True
                                            break
                                        else:
                                            # 如果弹框仍然显示，尝试JavaScript点击
                                            self.driver.execute_script("arguments[0].click();", agree_buttons[0])
                                            time.sleep(1)
                                            if not dialogs[0].is_displayed():
                                                self.logger.info("✅ 通过JavaScript关闭协议弹框")
                                                print("✅ 协议确认成功")
                                                sys.stdout.flush()
                                                agree_clicked = True
                                                break
                                    except Exception as click_e:
                                        self.logger.warning(f"点击同意按钮失败: {click_e}")
                                        continue
                            except Exception as find_e:
                                self.logger.warning(f"查找同意按钮失败 {selector}: {find_e}")
                                continue
                        
                        if not agree_clicked:
                            self.logger.warning("⚠️ 无法自动点击同意按钮")
                            print("⚠️ 无法自动确认协议，请手动点击'同意'按钮")
                            sys.stdout.flush()
                    else:
                        self.logger.info("ℹ️ 弹框不是协议相关，跳过处理")
                        print("ℹ️ 发现其他类型弹框，跳过处理")
                        sys.stdout.flush()
                else:
                    # 没有标题的情况，直接尝试查找同意按钮
                    self.logger.info("尝试直接查找同意按钮...")
                    agree_buttons = self.driver.find_elements(By.XPATH, '//button[contains(text(), "同意")]')
                    if agree_buttons and agree_buttons[0].is_displayed():
                        self.logger.info("🔘 发现同意按钮，尝试点击...")
                        print("🔘 发现同意按钮，正在点击...")
                        sys.stdout.flush()
                        try:
                            agree_buttons[0].click()
                            time.sleep(1)
                            self.logger.info("✅ 点击同意按钮成功")
                            print("✅ 协议确认成功")
                            sys.stdout.flush()
                        except Exception as e:
                            self.logger.warning(f"点击同意按钮失败: {e}")
                            print("⚠️ 无法自动确认协议，请手动点击'同意'按钮")
                            sys.stdout.flush()
            else:
                self.logger.info("ℹ️ 未发现协议弹框")
                print("ℹ️ 未发现协议弹框")
                sys.stdout.flush()
                
        except Exception as e:
            self.logger.error(f"处理协议弹框时出错: {e}")
            print("⚠️ 处理协议弹框时出错，请手动确认")
            sys.stdout.flush()
    
    def _verify_login_page_opened(self):
        """验证登录页面是否成功打开"""
        try:
            self.logger.info("🔍 验证登录页面是否打开...")
            
            # 等待页面跳转或加载
            max_wait = 10
            for attempt in range(max_wait):
                time.sleep(1)
                
                # 检查当前窗口数量
                window_handles = self.driver.window_handles
                current_url = self.driver.current_url
                
                self.logger.info(f"尝试 {attempt+1}/{max_wait}: URL={current_url}, 窗口数={len(window_handles)}")
                
                # 如果有多个窗口，切换到最新的窗口
                if len(window_handles) > 1:
                    self.logger.info("🔄 检测到新窗口，切换到登录窗口...")
                    self.driver.switch_to.window(window_handles[-1])
                    time.sleep(2)
                    current_url = self.driver.current_url
                    self.logger.info(f"切换后URL: {current_url}")
                
                # 检查是否在登录页面
                login_indicators = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_page_indicator'])
                login_form = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_form'])
                
                if login_indicators or login_form or "login" in current_url:
                    self.logger.info("✅ 检测到登录页面元素")
                    return True
                
                # 检查URL是否发生了变化（可能跳转中）
                if "login" in current_url or current_url != self.driver.current_url:
                    self.logger.info("🔄 URL正在变化，继续等待...")
                    continue
            
            self.logger.warning("⚠️ 登录页面验证超时")
            return False
            
        except Exception as e:
            self.logger.error(f"验证登录页面失败: {e}")
            return False
    
    def debug_page_info(self):
        """调试：显示当前页面信息"""
        try:
            window_handles = self.driver.window_handles
            current_window = self.driver.current_window_handle
            
            print(f"\n🔍 页面调试信息:")
            print(f"  窗口数量: {len(window_handles)} 个")
            
            # 检查所有窗口
            for i, handle in enumerate(window_handles):
                try:
                    self.driver.switch_to.window(handle)
                    current_url = self.driver.current_url
                    page_title = self.driver.title
                    is_mobile = "m.taobao.com" in current_url
                    is_current = handle == current_window
                    
                    print(f"\n  窗口 {i+1} {'(当前)' if is_current else ''}:")
                    print(f"    URL: {current_url}")
                    print(f"    标题: {page_title}")
                    print(f"    版本: {'手机版' if is_mobile else 'PC版'}")
                    
                    # 检查关键元素
                    login_indicators = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_page_indicator'])
                    login_form = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_form'])
                    login_text = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['login_text_indicator'])
                    
                    print(f"    登录页面元素: {len(login_indicators)} 个")
                    print(f"    登录表单: {len(login_form)} 个")
                    print(f"    登录提示文本: {len(login_text)} 个")
                    
                    if login_text:
                        print(f"    登录提示内容: {login_text[0].text[:50]}...")
                    
                    # 如果检测到登录页面，显示表单元素
                    if login_form:
                        username_inputs = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['username_input'])
                        password_inputs = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['password_input'])
                        submit_buttons = self.driver.find_elements(By.CSS_SELECTOR, self.config.SELECTORS['login']['submit_button'])
                        
                        print(f"    用户名输入框: {len(username_inputs)} 个")
                        print(f"    密码输入框: {len(password_inputs)} 个")
                        print(f"    登录按钮: {len(submit_buttons)} 个")
                        
                        if len(username_inputs) > 0 and len(password_inputs) > 0:
                            print(f"    ✅ 登录表单完整，可以进行交互式登录")
                    
                except Exception as window_e:
                    print(f"  窗口 {i+1} 信息获取失败: {window_e}")
            
            # 回到当前窗口
            self.driver.switch_to.window(current_window)
                
        except Exception as e:
            self.logger.error(f"获取页面调试信息失败: {e}")
    
    def set_login_confirmation_callback(self, callback):
        """设置登录确认回调函数"""
        self.login_confirmation_callback = callback
    
    def set_verification_callback(self, callback):
        """设置验证码处理回调函数"""
        self.verification_callback = callback
    
    def set_credential_input_callback(self, callback):
        """设置凭证输入回调函数"""
        self.credential_input_callback = callback


if __name__ == "__main__":
    """主函数 - 第一阶段测试：基础导航和登录检测"""
    print("🎯 TaoBao商城自动化爬虫 - 第一阶段测试")
    print("=" * 60)
    
    # 测试店铺URL
    test_shop_url = "https://shop185716543.taobao.com/"
    
    print(f"📍 测试店铺: {test_shop_url}")
    print("🔧 第一阶段: 基础导航和登录检测")
    print("-" * 60)
    
    try:
        with TaoBaoScraper(headless=False, debug=True) as scraper:
            print("✅ 爬虫初始化成功")
            
            # 第一步：直接导航到登录页面
            print("\n📡 第一步：导航到登录页面...")
            if scraper.navigate_to_login_page():
                print("✅ 登录页面导航成功")
                
                # 第二步：交互式登录
                print("\n🔐 第二步：交互式登录...")
                scraper.debug_page_info()  # 显示调试信息
                if scraper.login_taobao():
                    print("🎉 登录流程完成！")
                    
                    # 第三步：登录成功后导航到店铺页面
                    print("\n🔄 第三步：导航到目标店铺页面...")
                    time.sleep(3)
                    
                    if scraper.navigate_to_shop(test_shop_url):
                        print("✅ 已导航到店铺页面")
                        
                        # 第四步：验证登录后状态
                        print("\n🔄 第四步：验证登录后状态...")
                        
                        # 验证登录状态
                        if not scraper.check_login_required():
                            print("🎊 完美！已登录状态，可以开始抓取商品数据")
                        else:
                            print("⚠️ 仍需登录，可能登录未完全成功")
                    else:
                        print("❌ 无法导航到店铺页面")
                else:
                    print("❌ 登录流程失败")
            else:
                print("❌ 无法导航到登录页面")
            
            print("\n" + "="*60)
            print("🎯 第一阶段测试完成")
            print("✅ 如果上述流程顺利，可以开始第二阶段：商品列表抓取")
            
            # 自动进行第二阶段测试
            try:
                print("\n🎯 自动进行第二阶段测试：商品列表抓取")
                user_input = 'y'  # 默认进行测试
                if user_input == 'y':
                    print("\n🎯 开始第二阶段测试：商品列表抓取")
                    print("="*60)
                    
                    # 确保在正确的页面
                    if test_shop_url not in scraper.driver.current_url:
                        print("🔄 导航到店铺页面...")
                        scraper.navigate_to_shop(test_shop_url)
                        time.sleep(2)
                    
                    # 获取商品列表
                    print("📦 获取商品列表...")
                    products = scraper.get_product_list()
                    
                    if products:
                        print(f"✅ 成功获取 {len(products)} 个商品")
                        
                        # 显示前几个商品的基本信息
                        print("\n📋 商品预览：")
                        for i, product in enumerate(products[:3], 1):
                            title = product.get('title', 'N/A')
                            price = product.get('price_display', 'N/A')
                            print(f"  {i}. {title[:50]}... (价格: {price})")
                        
                        # 保存商品列表数据（移除不能序列化的WebElement）
                        products_to_save = []
                        for product in products:
                            clean_product = {k: v for k, v in product.items() if k != 'card_element'}
                            products_to_save.append(clean_product)
                        
                        scraper.save_products_data(products_to_save)
                        print("✅ 商品列表数据已保存")
                        
                        # 自动测试商品详情获取
                        try:
                            print("\n🎯 自动测试商品详情获取（前2个商品）")
                            detail_input = 'y'  # 默认进行测试
                            if detail_input == 'y':
                                print("\n🔍 开始测试商品详情获取...")
                                print("="*60)
                                
                                # 获取前2个商品的详情
                                detailed_products = scraper.get_product_details(products[:2])
                                
                                if detailed_products:
                                    print(f"✅ 成功获取 {len(detailed_products)} 个商品详情")
                                    
                                    # 保存详情数据（也要清理WebElement）
                                    detailed_to_save = []
                                    for product in detailed_products:
                                        clean_product = {k: v for k, v in product.items() if k != 'card_element'}
                                        detailed_to_save.append(clean_product)
                                    
                                    scraper.save_products_data(detailed_to_save, filename="taobao_products_detailed.json")
                                    print("✅ 商品详情数据已保存")
                                    
                                    # 生成API格式输出并打印预览
                                    print("\n🔄 生成API格式数据...")
                                    scraper.print_api_format_data(detailed_to_save)
                                    
                                    print("\n📋 API格式数据预览：")
                                    for i, product in enumerate(detailed_to_save[:2], 1):
                                        api_product = scraper.convert_to_api_format(product)
                                        if api_product:
                                            print(f"  {i}. {api_product['product_name'][:50]}...")
                                            print(f"     品牌: {api_product['product_type']}")
                                            print(f"     商品ID: {api_product['platform_product_id']}")
                                            print(f"     产品数据字段数: {len(api_product['product_data'].split(';')) if api_product['product_data'] else 0}")
                                            print(f"     详情页URL: {api_product['product_url']}")
                                else:
                                    print("❌ 获取商品详情失败")
                            else:
                                print("⏸️ 跳过商品详情测试")
                        except KeyboardInterrupt:
                            print("\n⚠️ 用户中断操作")
                        
                        print("\n🎯 第二阶段测试完成")
                        print("💡 下一步可以测试商品详情抓取功能")
                    else:
                        print("❌ 获取商品列表失败")
                else:
                    print("⏸️ 跳过第二阶段测试")
            except KeyboardInterrupt:
                print("\n⚠️ 用户中断操作")
            
            print("⏸️ 浏览器将保持打开5秒，供你查看...")
            time.sleep(5)
            
    except Exception as e:
        print(f"❌ 测试失败: {e}")
        import traceback
        traceback.print_exc() 